package com.roden.study.java.util.concurrent;

import org.junit.Test;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.FutureTask;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

/**
 * @author Roden
 */
public class CallableTest implements Callable<String> {

    @Override
    public String call() throws Exception {
        return "success";
    }

    public static void main(String[] args) throws Exception {
        Callable<String> callable=new CallableTest();
        FutureTask<String> ft= new FutureTask(callable);
        Thread thread=new Thread(ft);
        thread.start();
        System.out.println(ft.get());
    }
    
    @Test
    public void sumThread() throws ExecutionException, InterruptedException {
        long currentTimeMillis = System.currentTimeMillis();
        List<Integer> integerList= Arrays.asList(3,5,8,7,6);
        List<FutureTask<Integer>> futureTasks=new ArrayList<>(integerList.size());
        for(Integer value:integerList){
            FutureTask<Integer> futureTask=new FutureTask<>(()->{
                Thread.sleep(5000);
                return value;
            });
            futureTasks.add(futureTask);
            Thread thread=new Thread(futureTask);
            thread.start();
        }
        int sum=0;
        for(FutureTask<Integer> futureTask:futureTasks){
            sum+=futureTask.get();
        }
        //execute time: 5036 ,rusult is 29
        System.out.println("execute time: "+(System.currentTimeMillis()-currentTimeMillis)+" ,rusult is "+ sum);

    }

    @Test
    public void sumThreadPool() throws ExecutionException, InterruptedException {
        long currentTimeMillis = System.currentTimeMillis();
        List<Integer> integerList= Arrays.asList(3,5,8,7,6);
        List<FutureTask<Integer>> futureTasks=new ArrayList<>(integerList.size());
        ExecutorService executors=new ThreadPoolExecutor(4,10,60, TimeUnit.SECONDS,new LinkedBlockingQueue<Runnable>());
        for(Integer value:integerList){
            FutureTask<Integer> futureTask=new FutureTask<>(()->{
                Thread.sleep(5000);
                return value;
            });
            futureTasks.add(futureTask);
            executors.submit(futureTask);
        }
        int sum=0;
        for(FutureTask<Integer> futureTask:futureTasks){
            sum+=futureTask.get();
        }
        executors.shutdown();
        //execute time: 10047 ,rusult is 29
        System.out.println("execute time: "+(System.currentTimeMillis()-currentTimeMillis)+" ,rusult is "+ sum);  
    }
    
}
